package com.example.night.service.ApiService;

import com.example.night.data.Influencer.Influencer;
import com.example.night.data.Influencer.InfluencerPackage;
import com.example.night.data.Influencer.InfluencerResponse;
import com.example.night.service.ApiService.Token.TokenService;
import com.example.night.service.ApiService.Token.TokenUpdatedEvent;
import com.example.night.service.MysqlService.InfluencerMysqlService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.event.EventListener;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class InfluencerSummaryService {

    private static final Logger logger = LoggerFactory.getLogger(InfluencerSummaryService.class);

    private final InfluencerMysqlService influencerMysqlService;
    private final InfluencerService influencerService;
    private final InfluencerCoinsService influencerCoinsService;

    private final RestTemplate restTemplate;
    private final TokenService tokenService;
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final ReentrantLock lock = new ReentrantLock(); // 线程锁
    private String token;

    private List<InfluencerPackage> day45InfluencerPackageList = new ArrayList<>();

    private static final String TAL_URL = "https://api.jiutool.com/institutionHomeTwo/workbench/issue_talent";
    private static final String INS_URL = "https://api.jiutool.com/institutionHomeTwo/workbench/issue_institution";

    public InfluencerSummaryService(InfluencerMysqlService influencerMysqlService, InfluencerService influencerService, InfluencerCoinsService influencerCoinsService, RestTemplate restTemplate, TokenService tokenService) {
        this.influencerMysqlService = influencerMysqlService;
        this.influencerService = influencerService;
        this.influencerCoinsService = influencerCoinsService;
        this.restTemplate = restTemplate;
        this.tokenService = tokenService;
        token = tokenService.getToken();
    }
    @EventListener
    public void handleTokenUpdated(TokenUpdatedEvent event) {
        token = event.getNewToken();
    }
    /**
     * 获取所有达人数据（自动遍历所有分页）
     *
     * @param startTime 开始时间 (格式: yyyy-MM-dd)
     * @param endTime   结束时间 (格式: yyyy-MM-dd)
     * @return `List<Influencer>` 达人列表
     */
    public String getUrl(int type, int pageNum, String startTime, String endTime, String promoterId) {
        String baseUrl = "";
        switch (type) {
            case 1:
                baseUrl = UriComponentsBuilder.fromHttpUrl(INS_URL)
                    .queryParam("page", pageNum)
                    .queryParam("limit", 10)
                    .queryParam("sort_type", "")
                    .queryParam("start_time", startTime)
                    .queryParam("end_time", endTime)
                    .queryParam("f_institution_name", "")
                    .toUriString();
                break;
            case 2:
                baseUrl = UriComponentsBuilder.fromHttpUrl(TAL_URL)
                    .queryParam("page", pageNum)
                    .queryParam("limit", 10)
                    .queryParam("sort_type", "")
                    .queryParam("start_time", startTime)
                    .queryParam("end_time", endTime)
                    .queryParam("author_account", "")
                    .queryParam("author_short_id", "")
                    .toUriString();
                break;
        }
        return baseUrl;
    }

    public List<InfluencerPackage> responseToListInfluencerPackage(ResponseEntity<String> response, int type) throws JsonProcessingException {
        List<InfluencerPackage> influencerPackages= new ArrayList<>();

        if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
            InfluencerResponse influencerResponse = null;
            try {
                influencerResponse = objectMapper.readValue(response.getBody(), InfluencerResponse.class);
            } catch (JsonProcessingException e) {
                System.out.println("response.getBody(): " + response.getBody());
            }

            if (influencerResponse.getData() != null) {
                List<Influencer> influencers = influencerResponse.getData().getInfluencers();
                for (Influencer influencer : influencers) {
                    InfluencerPackage influencerPackage = new InfluencerPackage();
                    if (type == 1) {
                        influencerPackage.setPromoteId(influencer.getFInstitutionId());
                        influencerPackage.setPromoteName(influencer.getFInstitutionName());
                        influencerPackage.setRoleType(1);
                    } else if (type == 2) {
                        influencerPackage.setPromoteId(influencer.getAuthorShortId());
                        influencerPackage.setPromoteName(influencer.getAuthorAccount());
                        influencerPackage.setRoleType(2);
                    }

                    influencerPackage.setTotalOrders(influencer.getAllOrderTotal());
                    influencerPackage.setTotalGMV(influencer.getAllTotalPayAmount());

                    influencerPackages.add(influencerPackage);
                }
            }
        } else {
            logger.error("获取达人数据失败，状态码: {}", response.getStatusCode());
        }

        return influencerPackages;
    }

    public List<InfluencerPackage> fetchInfluencers(String startTime, String endTime, int pageNum, int type, String promoterId) {
        try {
            // 获取 Token
            token = tokenService.getToken();
            if (token == null || token.isEmpty()) {
                logger.error("获取达人数据失败：Token 为空，请检查登录状态");
                return Collections.emptyList();
            }

            List<Influencer> allInfluencers = new ArrayList<>();
            int page = 1;
            int lastPage = 1;

            // 构造请求头
            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "Bearer " + token);  // 设置 Authorization 请求头
            headers.set("X-Csrf-Token", token);     // 设置 CSRF Token
            headers.set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            // 构造请求体
            HttpEntity<String> requestEntity = new HttpEntity<>(headers);

            List<InfluencerPackage> influencerPackages= new ArrayList<>();

            if (type == 1 || type == 2) {
                // 构建 URL
                String url = getUrl(type, pageNum, startTime, endTime, promoterId);
                // 发送 GET 请求
                ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);

                influencerPackages.addAll(responseToListInfluencerPackage(response, type));
            } else {
                String url1 = getUrl(1, pageNum, startTime, endTime, promoterId);
                String url2 = getUrl(2, pageNum, startTime, endTime, promoterId);

                CompletableFuture<List<InfluencerPackage>> future1 = CompletableFuture.supplyAsync(() -> {
                    ResponseEntity<String> response = restTemplate.exchange(url1, HttpMethod.GET, requestEntity, String.class);
                    try {
                        return responseToListInfluencerPackage(response, 1);
                    } catch (JsonProcessingException e) {
                        throw new RuntimeException(e);
                    }
                });

                CompletableFuture<List<InfluencerPackage>> future2 = CompletableFuture.supplyAsync(() -> {
                    ResponseEntity<String> response = restTemplate.exchange(url2, HttpMethod.GET, requestEntity, String.class);
                    try {
                        return responseToListInfluencerPackage(response, 2);
                    } catch (JsonProcessingException e) {
                        throw new RuntimeException(e);
                    }
                });

                CompletableFuture<Void> allDone = CompletableFuture.allOf(future1, future2);

                try {
                    // 等待全部任务完成
                    allDone.get();

                    // 合并两个结果
                    influencerPackages.addAll(future1.get());
                    influencerPackages.addAll(future2.get());

                    // 排序
                    influencerPackages.sort(Comparator.comparingDouble(InfluencerPackage::getTotalGMV).reversed());

                    // 使用排序后的数据
//                    System.out.println("排序后数据: " + influencerPackages);
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
            return influencerPackages;

        } catch (JsonProcessingException e) {

            throw new RuntimeException(e);
        }

    }
    public List<InfluencerPackage> getAllInfluencers(String startTime, String endTime) {
        // 获取 Token
        token = tokenService.getToken();
        if (token == null || token.isEmpty()) {
            logger.error("获取达人数据失败：Token 为空，请检查登录状态");
            return Collections.emptyList();
        }
        int lastPage = 1;
        List<InfluencerPackage> influencerPackages = new ArrayList<>();

        // 构造请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + token);  // 设置 Authorization 请求头
        headers.set("X-Csrf-Token", token);  // 设置 CSRF Token
        headers.set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        HttpEntity<String> requestEntity = new HttpEntity<>(headers);

        try {
            // 构建第一页 URL
            String url = getUrl(2, 1, startTime, endTime, "");
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                InfluencerResponse influencerResponse = null;
                try {
                    influencerResponse = objectMapper.readValue(response.getBody(), InfluencerResponse.class);
                } catch (JsonProcessingException e) {
                    logger.error("JSON解析失败，响应内容: {}", response.getBody(), e);
                }

                if (influencerResponse != null && influencerResponse.getData() != null) {
                    List<Influencer> influencers = influencerResponse.getData().getInfluencers();
                    lastPage = influencerResponse.getData().getLastPage();
//                    logger.info("第一页获取成功，共 {} 个达人，最后页码：{}", influencers.size(), lastPage);

                    for (Influencer influencer : influencers) {
                        InfluencerPackage influencerPackage = new InfluencerPackage();
                        influencerPackage.setPromoteId(influencer.getAuthorShortId());
                        influencerPackage.setPromoteName(influencer.getAuthorAccount());
                        influencerPackage.setRoleType(0);
                        influencerPackage.setTotalOrders(influencer.getAllOrderTotal());
                        influencerPackage.setTotalGMV(influencer.getAllTotalPayAmount());
                        influencerPackages.add(influencerPackage);
                    }
                } else {
                    logger.warn("达人数据获取失败或返回为空");
                }
            } else {
                logger.error("请求第一页失败，状态码：{}", response.getStatusCode());
            }

            // 创建线程池
            ExecutorService executorService = Executors.newFixedThreadPool(8);  // 设置合适的线程数
            List<Future<List<InfluencerPackage>>> futures = new ArrayList<>();

            // 从第二页开始多线程处理
            for (int page = 2; page <= lastPage; page++) {
                final int currentPage = page;
                futures.add(executorService.submit(() -> {
                    String pageUrl = getUrl(2, currentPage, startTime, endTime, "");
                    ResponseEntity<String> pageResponse = restTemplate.exchange(pageUrl, HttpMethod.GET, requestEntity, String.class);
//                    logger.info("正在获取第 {} 页数据", currentPage);
                    return responseToListInfluencerPackage(pageResponse, 2);
                }));
            }

            // 等待所有任务完成并收集结果
            for (Future<List<InfluencerPackage>> future : futures) {
                try {
                    influencerPackages.addAll(future.get());
                } catch (InterruptedException e) {
                    logger.error("线程被中断：{}", e.getMessage());
                    Thread.currentThread().interrupt();
                } catch (ExecutionException e) {
                    logger.error("获取分页数据失败：{}", e.getMessage());
                }
            }

            // 优雅关闭线程池
            executorService.shutdown();
            try {
                if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();
                    if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                        logger.error("线程池未能正常关闭");
                    }
                }
            } catch (InterruptedException e) {
                logger.error("线程池关闭中断：{}", e.getMessage());
                executorService.shutdownNow();
                Thread.currentThread().interrupt();
            }

        } catch (Exception e) {
            logger.error("获取达人列表失败：{}", e.getMessage(), e);
        }

        logger.info("共获取到 {} 个达人信息", influencerPackages.size());
        return influencerPackages;
    }


    @PostConstruct
    @Scheduled(cron = "0 3 0 * * ?")
    public void get45DayInfluencerData() throws ParseException {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime thirtyDaysAgo = now.minusDays(45);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        String startDate = thirtyDaysAgo.format(formatter);
        String endDate = now.format(formatter);

        day45InfluencerPackageList = getAllInfluencers(startDate, endDate);
        influencerMysqlService.saveInfluencers(day45InfluencerPackageList);
        influencerService.updateRegisteredInfluencerPackages();
        influencerService.getLastMonthInfluencersData();
        influencerCoinsService.getRegisteredInfluencersWithStats();

/*        influencerMysqlService.creatTables(day45InfluencerPackageList);*/
    }


}
